package com.metis.document.parse.dialog.utils;


import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.jetbrains.annotations.NotNull;

public class MessageDigestInputStream extends InputStream {
    public static final int EOF = -1;


    /**
     * 已读取的字节数
     */
    private int readByteCount = 0;
    private final InputStream deleteInputStream;
    private final MessageDigest messageDigest;
    private byte[] digest;

    public MessageDigestInputStream(@NotNull final InputStream deleteInputStream, @NotNull final String algorithm) throws NoSuchAlgorithmException {
        this.deleteInputStream = deleteInputStream;
        this.messageDigest = MessageDigest.getInstance(algorithm);
    }

    public MessageDigestInputStream(@NotNull final InputStream deleteInputStream){
        this.deleteInputStream = deleteInputStream;
        try {
            this.messageDigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        }
    }

    public MessageDigest getMessageDigest() {
        return messageDigest;
    }
    public String getChecksum(){
        return String.format("%s%%%s", getMessageDigest().getAlgorithm(), getHexString().toUpperCase());
    }
    public synchronized String getHexString() {
        if (this.digest == null) {
            digest = messageDigest.digest();
        }
        StringBuilder sb = new StringBuilder();
        for (byte b : digest) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    private void updateMessageDigest(final int input) {
        messageDigest.update((byte) input);
    }

    private void updateMessageDigest(final byte[] input, final int offset, final int length) {
        messageDigest.update(input, offset, length);
    }

    @Override
    public int read() throws IOException {
        int result = deleteInputStream.read();
        if (result != EOF) {
            readByteCount++;
            updateMessageDigest(result);
        }
        return result;
    }

    @Override
    public int read(byte @NotNull [] b) throws IOException {
        return read(b, 0, b.length);
    }

    @Override
    public int read(byte @NotNull [] b, int off, int len) throws IOException {
        int result = deleteInputStream.read(b, off, len);
        if (result != EOF) {
            updateMessageDigest(b, off, result);
            readByteCount += result;
        }
        return result;
    }

    @Override
    public long skip(long n) throws IOException {
        return deleteInputStream.skip(n);
    }

    @Override
    public int available() throws IOException {
        return deleteInputStream.available();
    }

    @Override
    public void close() throws IOException {
        deleteInputStream.close();
    }

    @Override
    public void mark(int readlimit) {
        deleteInputStream.mark(readlimit);
    }

    @Override
    public void reset() throws IOException {
        deleteInputStream.reset();
    }

    @Override
    public boolean markSupported() {
        return deleteInputStream.markSupported();
    }

    /**
     * 返回已读取的字节数
     */
    public int getReadByteCount() {
        return readByteCount;
    }
}
